﻿/*******************************************************************************
 * Copyright © 2017 FriendStar.Framework 版权所有
 * Author: HYF
 * Description: FriendStar快速开发平台
 * Website：http://www.FriendStar.cn
*********************************************************************************/
using FriendStar.Code;
using FriendStar.Data.DBContext;
using SqlSugarRepository;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text.RegularExpressions;

namespace FriendStar.Data
{
    /// <summary>
    /// 仓储实现
    /// </summary>
    public class RepositoryBase : IRepositoryBase, IDisposable
    {
        private ISqlSugarClient dbcontext = SugarDbContext.GetInstance();
        public IRepositoryBase BeginTrans()
        {
            dbcontext.BeginTran();
            return this;
        }
        public DbParameter[] GetParameters(object obj)
        {
           return dbcontext.GetParameters(obj);
        }
        public int GetParameterIndex(DbParameter[] parameters, string parameterName)
        {
            int index = -1;
            if(parameters!=null)
            {
                foreach(var par in parameters)
                {
                    index++;
                    if(par.ParameterName.ToLower()== parameterName.ToLower()) { break; }
                }
            }
            return index;
        }

        public void Commit()
        {
            try
            {
                //提交事务
                dbcontext.CommitTran();
            }
            catch (Exception)
            {
                if (dbcontext != null)
                {
                    dbcontext.RollbackTran();//回滚事务
                }
                throw;
            }
        }
        public void RollBack()
        {
            if (dbcontext != null)
            {
                dbcontext.RollbackTran();//回滚事务
            }
        }
        public void Dispose()
        {
            if (dbcontext != null)
            {
                dbcontext.Dispose();
            }
        }
        public bool Insert<TEntity>(TEntity entity) where TEntity : class
        {
            var result = dbcontext.Insert<TEntity>(entity);
            return result == null ? false : true;
        }
        public bool Insert<TEntity>(List<TEntity> entitys) where TEntity : class
        {
            return dbcontext.SqlBulkCopy(entitys);
        }
        public bool Update<T>(object rowObj, Expression<Func<T, bool>> expression) where T : class
        {
            return dbcontext.Update<T>(rowObj, expression);
        }
        public bool Update<TEntity>(TEntity entity) where TEntity : class
        {
            List<string> list = new List<string>();
            PropertyInfo[] props = entity.GetType().GetProperties();
            foreach (PropertyInfo prop in props)
            {
                if (prop.GetValue(entity, null) == null)
                {
                    list.Add(prop.Name);
                    continue;
                }
                if (prop.GetValue(entity, null).ToString() == "&nbsp;")
                {
                    entity.GetType().GetProperty(prop.Name).SetValue(entity, null, null);
                }
            }
            //清空禁止更新列
            dbcontext.DisableUpdateColumns = null;
            dbcontext.AddDisableUpdateColumns(list.ToArray());
            return dbcontext.Update<TEntity>(entity);
        }
        public bool UpdateColumns<T>(T rowObj, Expression<Func<T, bool>> expression, Expression<Func<T, object>> updateColumns) where T : class
        {
            return dbcontext.UpdateColumns<T>(rowObj, expression, updateColumns);
        }
        public bool Delete<TEntity>(TEntity entity) where TEntity : class
        {
            return dbcontext.Delete<TEntity>(entity);
        }
        public bool Delete<TEntity>(Expression<Func<TEntity, bool>> filterExpression) where TEntity : class
        {
            return dbcontext.Delete<TEntity>(filterExpression);
        }
        public TEntity FindEntity<TEntity>(object keyValue) where TEntity : class, new()
        {
            return dbcontext.Queryable<TEntity>().InSingle(keyValue);
        }
        public TEntity FindEntity<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class, new()
        {
            return dbcontext.Queryable<TEntity>().Where(predicate).FirstOrDefault();
        }
        public ISugarQueryable<TEntity> IQueryable<TEntity>() where TEntity : class, new()
        {
            return dbcontext.Queryable<TEntity>();
        }
        public ISugarQueryable<TEntity> IQueryable<TEntity>(string tableName) where TEntity : class, new()
        {
            return dbcontext.Queryable<TEntity>(tableName);
        }
        public ISugarQueryable<TEntity> IQueryable<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class, new()
        {
            return dbcontext.Queryable<TEntity>().Where(predicate);
        }
        public List<TEntity> FindList<TEntity>(string strSql) where TEntity : class
        {
            return dbcontext.SqlQuery<TEntity>(strSql);
        }
        public List<TEntity> FindList<TEntity>(string strSql, object dbParameter) where TEntity : class
        {
            return dbcontext.SqlQuery<TEntity>(strSql, dbParameter).ToList<TEntity>();
        }
        public List<TEntity> FindList<TEntity>(Pagination pagination) where TEntity : class, new()
        {
            //获取排序字段
            string order = Pagination.GetOrder(pagination);
            pagination.records = dbcontext.Queryable<TEntity>().Count();
            return dbcontext.Queryable<TEntity>().OrderBy(order).ToPageList(pagination.page, pagination.rows);
        }
        public List<TEntity> FindList<TEntity>(Expression<Func<TEntity, bool>> predicate, Pagination pagination) where TEntity : class, new()
        {
            //获取排序字段
            string order = Pagination.GetOrder(pagination);
            pagination.records = dbcontext.Queryable<TEntity>().Where(predicate).Count();
            return dbcontext.Queryable<TEntity>().Where(predicate).OrderBy(order).ToPageList(pagination.page, pagination.rows);
        }

        #region 存储过程执行
        /// <summary>
        /// 执行存储过程、参数
        public List<TEntity> ExecuteStoredProcedure<TEntity>(string storedProcedureName, object obj)
        {
            List<TEntity> list = new List<TEntity>();
            dbcontext.IsClearParameters = false;//禁止清除参数
            dbcontext.CommandType = CommandType.StoredProcedure;//指定为存储过程
            list = dbcontext.SqlQuery<TEntity>(storedProcedureName, obj);
            dbcontext.IsClearParameters = true;//可以清除参数
            dbcontext.CommandType = CommandType.Text;//还原回默认
            return list;
        }

        #endregion
    }
}
